﻿using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Web;
using System.Net;
using System.Diagnostics;
using System.Xml;
using PandoraMusicBox.Engine;
using PandoraMusicBox.Engine.Data;
using PandoraMusicBox.Engine.Encryption;
using System.Collections;
using System.Drawing;
using System.Windows.Forms;
using System.ComponentModel;
using Engine;
using System.Threading;
using WinampProxyNS;



/*
 * Remember every new plug in must have new GUIDS, there are 3:
 * The Interface class (IRRExtension.cs), the RRExtension class (RRExtsion.cs)
 * and in the properties for the ASSEMBLY (AssemblyInfo.cs)
*/

namespace RRPandora
{
    [Guid("435E330C-E544-4C7F-813B-CB8AD937FA5C")]
	[ClassInterface(ClassInterfaceType.None)]
	public class RRExtension : RRPandora.IRRExtension
	{
		private enum ProcessCommandResults
		{
			CommandNotProcessed = 0,
			CommandProcessedReturnPrevScreen = 1,
			CommandProcessedStayOnScreen = 2,
			CommandModified = 3
		}

        private enum SettingNames
        {
            Username = 1,
            Password = 2, 
            LastStationId = 3,
            SkipOnHate = 4,
            PlayState = 5,
            PlayName = 6,
            ActiveList = 7,
            PlayItem = 8,

        }

#region Variables
        //winamp variables
        private WinampProxy MyWinAmp = new WinampProxy("RRPandora");
        private bool WINAMP_HIDE = false;
        private String PlayItem;
        private String PlayName;
        private bool ShouldPlay;
        private int EqAsk;
        private bool GetNewVolume;
        private string ActiveList;
        private const string WebRadioRootList = "Root.txt";
        private string VisuWindowName = "!Winamp Gen!AVS";

        internal const string ENCRYPTION_PASSPHRASE = "ACC14F99-E12A-4FF4-B4B4-98766970287D";
        public XmlDocument SettingsXML = new System.Xml.XmlDocument();
        private Boolean isConnected;
        private String DPath;
        private Boolean isVisible = false;
        private int playpos = 0;
        private string[] MYCMD;

       // private IBasicAudio m_objBasicAudio = null;
        //current station
        private string _currentStationId = "";
        public static string _currentStationName = "";
        private Boolean _currentStationCanSkip = true;

        private string _currentSongLength;
        private string _currentSongPosition;
        private DateTime SongTime;
        TimeSpan CurrentSongLength;
        double TotalSecs;
        double CurrentSecs;
        int AdHold;

        

        //current song
        public static string _currentSongAlbum = "";
        private string _currentSongAlbumArtURL = "";
        private string _currentSongAlbumDetailsURL = "";
        public static Image _currentSongAlbumArtImage;
        Image _currentSongArtistImage;
        public static string _currentSongArtist = "";
        private string _currentSongArtistArtURL = "";
        private Boolean _currentSongIsAdvertisement = false;
        private string _currentSongMusicId = "";
        public static string _currentSongTitle = "";
        private string _currentSongTrackToken = "";

        RRPandora.AudioFormats _audioFormat;
        PandoraMusicBox.Engine.PandoraRating _currentSongRating;

        //session management

        private bool _success = false;
        //private bool _hasControl = false;
        public static Boolean _isConnected = false;
        private string _lastStationId = "";
        private Boolean _hasSession = false;
        private Boolean _isStartup = false;
        private Boolean IsResumingActive = false;

        private BackgroundWorker AuthWorker = new BackgroundWorker();
        private BackgroundWorker ConnectionWorker = new BackgroundWorker();
        private BackgroundWorker imageWorker = new BackgroundWorker();

        private System.Windows.Forms.Timer StatusTimer = new System.Windows.Forms.Timer();
        private System.Windows.Forms.Timer SongProgressTimer = new System.Windows.Forms.Timer();
        private System.Windows.Forms.Timer RefreshTimer = new System.Windows.Forms.Timer();
        private System.Windows.Forms.Timer OSKTextResetTimer = new System.Windows.Forms.Timer();
        private System.Windows.Forms.Timer ConnectionCheckTimer = new System.Windows.Forms.Timer();
        static EventWaitHandle _waitHandle = new AutoResetEvent(false);
        static EventWaitHandle _playHandle = new AutoResetEvent(false);
        //musicbox controls
        public static MusicBox musicBox = new PandoraMusicBox.Engine.MusicBox();
        PandoraIO pio = new PandoraIO();
        //public static DirectShowPlayer player = new DirectShowPlayer();

        //artwork
        private string _defaultAlbumArt = "DefaultAlbumArt.png";
        private Boolean albumStarted = false;
        private Boolean artistStarted = false;
        private Boolean altStarted = false;
        private Boolean albumDone = false;
        private Boolean artistDone = false;
        private Boolean altDone = false;
        WebClient albumclient = new WebClient();
        Image tempALImage = null;
        Image tempARImage = null;
        private DateTime _albumStartDate;
        private int albumValue = 0;
        private string albumStatusText = "";
        private DateTime _artistStartDate;
        private int artistValue = 0;
        private string artistStatusText = "";
        private int alCnt = 0;
        private int altCnt = 0;
        private int arCnt = 0;
        int scrpos = 0;
        private string MyCurrentTrackArt;

        //flicker
        //FlickerSearch.FlickerSearch FS = new FlickerSearch.FlickerSearch();
        //public static int FimageCount = 0;
        //public static int FlickerItems = 0;
        //public static List<Image> FlickerImages = new List<Image>();
        //public static Boolean UseFlicker = false;
        //public static Boolean imagesComplete = false;
        //public static string FlickerSearchTerm = "";

        //details
        WebBrowser wb = new WebBrowser();
        WebClient infoclient = new WebClient();
        private string artistInfoURL = @"http://pandora.com/xml/music/artist/";

        //misc
        private int location = 0;
        private Boolean artClick = false;
        private string _listsort = "StationName ASC";
        private Boolean _sortFav = false;
        RRPandora.Utility _util = new RRPandora.Utility();
        RRPandora.Station _station = new RRPandora.Station();
        RRPandora.Session _session = new RRPandora.Session();
        RRPandora.PandoraClient pclient;
        private string OSKText;

        //settings
        private string _userName = null;
        private string _password = null;
        private string DebugModeIndicator;
        private string SkipOnHateIndicator;
        private string HiddenPassword;
        private string DebugMode;
        private string _encryptedPassword;
        private string SkipOnHate;

        //indicators
        private string ThumbsUpInd;
        private string ThumbsDownInd;

        private const string SRCActiveScreen = "RRPandora_list.skin";
        private bool IsActive;
        private const string MainScreen = "RRPandora_list.skin";

#endregion

		#region Private Fields
		
		#endregion

		#region Constructor

		public RRExtension()
		{
			if (SDK.Created == false)
				SDK.SetSDK();
		}

		#endregion

		#region Public RRExtension API Methods (new ones)

		// This is called when the pluginmgr;about command is used
		//
		public void About(object frm)
		{
		}

		// This is called when the pluginmgr;settings command is used
		//
		public void Settings(object frm)
		{
            SDK.Execute("RRPANDORA_SETTINGS");
            
		}

        public void SourceActive(bool active)
        {
            if (IsActive == true && active == false)
            {
                this.ShouldPlay = this.MyWinAmp.enumWinampStatus == WinampStatusEnum.Playing;
                this.MyWinAmp.Stop();
                StatusTimer.Enabled = false;
                SongProgressTimer.Enabled = false;
                RefreshTimer.Enabled = false;
                ConnectionCheckTimer.Enabled = false;
                if (this.MyWinAmp.IsVisualRunning())
                {
                    this.MyWinAmp.Visual();
                }
            }
            else if (IsActive == false && active == true)
            {
                if (IsResumingActive)
                {
                    ToLog("Pandora resume state is true. Setting ShouldPlay to true.");
                    ShouldPlay = true;
                    ToLog("ShouldPlay set to is true.");
                    //start connection check to resume music when connection reestablished
                    ConnectionCheckTimer.Enabled = true;
                }
                if (ShouldPlay == true)
                {
                    ToLog("ShouldPlay is true, starting connection worker.");
                    if (!ConnectionWorker.IsBusy)
                    {
                        ConnectionWorker.RunWorkerAsync();
                        ToLog("Connection worker started");
                    }
                    //start connection check to resume music when connection reestablished
                    ConnectionCheckTimer.Enabled = true;
                }
                
            }
            this.IsActive = active;
            ToLog("------> RRPandora method SourceActive run with parameter of " + active);
        }

		#endregion

		#region Public RRExtension API Methods

		/// <summary>
		/// This is called ONLY once, right after plug-in is loaded
		/// use this to set up anything you need, including data storage
		/// </summary>
		/// <param name="pluginDataPath"></param>
        public void Initialize(string pluginDataPath)
        {
            /*
                pluginDataPath will contain a USER Profile (my documents) folder path
                suitable for storing WRITEABLE settings to
                this would make your plugin OS compliant (VISTA and onward)
                not to mention, its proper programming, user data should NOT be stored in "Program Files"
    		
             * example (typical vista): "C:\Users\Username\Documents\RideRunner\Plugins\MyPlugin\"
    
                App.path will be the path of the ACTUALL LOADED .dll (not recomend for any writes)
			
                uncomment code below if u need the directory
            */

            // use to create data storage folder
            if (Directory.Exists(pluginDataPath) == false)
            {
                Directory.CreateDirectory(pluginDataPath);
            }
            DPath = pluginDataPath;


            try
            {
                if (File.Exists(DPath + "RRPandora_debug.txt"))
                {
                    //restart debug file
                    File.Delete(DPath + "RRPandora_debug.txt");
                }
                LoadSettings();
                this.WINAMP_HIDE = bool.Parse(SDK.GetInfo("=$HIDEPLAYER$"));
               
                    ToLog("Settings Loaded");
            }
            catch (Exception err)
            {
                    ToLog(err.Message);
            }

            if (SDK.GetUserVar("player").ToLower() == "winamp")
                VisuWindowName = SDK.GetUserVar("visuname");

            try
            {
                this.MyWinAmp.StartWinamp(this.WINAMP_HIDE);
                ToLog("Winamp Started");
            }
            catch (Exception errmsg)
            {
                ToLog(errmsg.Message);
            }
            try
            {
                this.MyWinAmp.InitializeWinamp();
                MyWinAmp.SetRepeat(false);
                MyWinAmp.SetShuffle(false);
                ActiveList = "";
                ToLog("Winamp Initialized");
            }
            catch (Exception errmsg)
            {
                ToLog(errmsg.Message);
            }


            if (string.IsNullOrEmpty(this.ActiveList))
            {
                this.ActiveList = "Root.txt";
            }
            PlayName = "Pandora Playlist";
            PlayItem = "";
            if (PlayItem.StartsWith("!#"))
            {
                PlayItem = "";
            }
            try
            {
                PlayInWinamp(PlayItem, false);
                ToLog("Winamp Ready");
            }
            catch (Exception errmsg)
            {
                ToLog(errmsg.Message);
            }


            //if (UseFlicker)
           // {
                //int.TryParse(this.pluginConfig.ReadField("/APPCONFIG/FLICKERITEMS"), out FlickerItems);
                //FlickerSearchTerm = this.pluginConfig.ReadField("/APPCONFIG/FLICKERSEARCH");
           // }

            try 
            {
            PandoraIO.AudioFormat = _audioFormat.ToString();
            SongTime = new DateTime(2010, 1, 18, 00, 00, 00);
                    ToLog("Pandora audio format set");
            }
            catch (Exception err)
            {    
                    ToLog(err.Message);
            }

            try
            {
                AuthWorker.DoWork += new DoWorkEventHandler(AuthWorker_DoWork);
                AuthWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(AuthWorker_RunWorkerCompleted);
             
                    ToLog("Authorization handler initiated");
            }
            catch (Exception err)
            {
              
                    ToLog(err.Message);
            }

            try 
            {
                ConnectionWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(ConnectionWorker_RunWorkerCompleted);
                ConnectionWorker.DoWork += new DoWorkEventHandler(ConnectionWorker_DoWork);
              
                    ToLog("Connection handler initiated");
            }
            catch (Exception err)
            {
               
                    ToLog(err.Message);
            }

            try
            {
                albumclient.DownloadDataCompleted += new DownloadDataCompletedEventHandler(albumclient_DownloadDataCompleted);
                albumclient.DownloadProgressChanged += new System.Net.DownloadProgressChangedEventHandler(albumclient_DownloadProgressChanged);
          
                    ToLog("album client handler initiated");
            }
            catch (Exception err)
            {
               
                    ToLog(err.Message);
            }

            try
            {
                imageWorker.DoWork += new DoWorkEventHandler(imageWorker_DoWork);
                imageWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(imageWorker_RunWorkerCompleted);
          
                    ToLog("Image handler initiated");
            }
            catch (Exception err)
            {
             
                    ToLog(err.Message);
            }
            //infoclient.DownloadDataCompleted += new DownloadDataCompletedEventHandler(infoclient_DownloadDataCompleted);
            try
            {
                StatusTimer.Interval = 1000;
                StatusTimer.Tick += new EventHandler(StatusTimer_Tick);
                ConnectionCheckTimer.Interval = 250;
                ConnectionCheckTimer.Tick += new EventHandler(ConnectionCheckTimer_Tick);
                //StatusTimer.Enabled = true;
                SongProgressTimer.Interval = 1000;
                SongProgressTimer.Tick += new EventHandler(SongProgressTimer_Tick);
                RefreshTimer.Interval = 10000;
                RefreshTimer.Tick += new EventHandler(RefreshTimer_Tick);
                OSKTextResetTimer.Interval = 500;
                OSKTextResetTimer.Tick += new EventHandler(OSKTextResetTimer_Tick);
                //SongProgressTimer.Enabled = true;

          
                    ToLog("Status timer initiated");
            }
            catch (Exception err)
            {
            
                    ToLog("Image handler initiated");
            }

        }

		/// <summary>
		/// This is called when plugin manager is unloading plugin
		/// </summary>
        public void Terminate()
        {
            try
            {
                // clean up code goes here... 
                // close any file handles...free up any unmanaged resources
                // GC will take care of managed resources
                SaveToConfig(SettingNames.ActiveList, ActiveList);
                SaveToConfig(SettingNames.PlayName, PlayName);
                SaveToConfig(SettingNames.PlayState, MyWinAmp.enumWinampStatus.ToString());
                SaveToConfig(SettingNames.ActiveList, ActiveList);
                MyWinAmp.StopWinamp();
                _session.EndSession();
            }
            catch (Exception err)
            {
               
                    ToLog("problem with terminate procedure: " + err.Message);
            }

        }


		/// <summary>
		/// called by plugin manager
		/// </summary>
		/// <param name="state"></param>
		public void Enabled(bool state)
		{
			SDK.Enabled = state;
		}

		/// <summary>
		/// called by plugin manager
		/// </summary>
		/// <param name="item"></param>
		/// <returns></returns>
		public string Properties(string item)
		{
			string properties = "";

			switch (item)
			{
				case "version":
					properties = Assembly.GetExecutingAssembly().GetName().Version.ToString();
					break;
				case "author":
					properties = "Sonique Software Design";
					break;
                case "category":
					properties = "TBD";
					break;
                case "description":
					properties = "Pandora plugin for Ride Runner";
					break;
                case "supporturl":
                    properties = "http://www.mp3car.com/rr-plugins/150505-so-have-you-guys-ever-heard-of-this-new-thing-called-pandora.html";
					break;
                case "src_guid":
                    properties = "{E65D251E-CB77-4708-8810-A5A2DE928B93}";
                    break;
                case "src_activesource":
                    properties =  "RRPandora";
                    break;
                case "src_skin":
                    properties =  "RRPandora_list.skin";
                    break;
                case "menuitem":
                    properties = '\u0022' + "RRPandora" + '\u0022' + ",PANDORA,Icons\\Pandora.png,Pandora Internet Radio";
                    break;
			}

			return properties;
		}

		//*****************************************************************
		//* This Function will be called with the current command string
		//* The return parameter of this function determines the handling
		//* To be taken upon returning to RR:
		//*
		//* 0 = Command not processed here
		//* 1 = Command completed + return to previous screen
		//* 2 = Command completed, stay on current screen
		//* 3 = Command has been changed/modified, execute returned one
		//*
		//* frm is the form object which generated the current command. Be
		//* VERY VERY careful when using it.
		//* must use InvokeMember InterOp on this object
		//*
		//* frm.tag contains the screen name for the screen the CMD was processed on.
		//*****************************************************************
		public int ProcessCommand(ref string CMD, object frm)
		{
			ProcessCommandResults result = ProcessCommandResults.CommandNotProcessed;

			// Example:
			//string frmTag = (string)frm.GetType().InvokeMember("Tag", BindingFlags.GetProperty, null, frm, null);

            MYCMD = CMD.Split(new Char[] { ';' });

            switch (MYCMD[0].ToLower())
			{
				case "rrpandora":
                    try
                    {
                       
                        ToLog("RRPANDORA command executed");
                        
                        if (!IsActive)
                        {
      
                            SDK.Execute("VISU;0");
                            //_hasControl = true;
                            if (string.IsNullOrEmpty(_userName))
                            {
                                SDK.ErrScrn("RRPandora", "Error with login", "Please verify your username and password in settings");
                                SDK.Execute("RRPANDORA_SETTINGS");
                            }
                            else
                            {
                                if (!_hasSession)
                                    _isStartup = true;
                                ShouldPlay = true;
                                if (!ConnectionWorker.IsBusy)
                                    ConnectionWorker.RunWorkerAsync();
                                //if (UseFlicker)
                                //imageWorker.RunWorkerAsync();
                                StatusTimer.Start();
                                SDK.Execute("load;rrpandora_list.skin");
                                SDK.Execute("CLCLEAR;ALL");
                                SDK.Execute("CLADD;Loading Stations");
                            }
                        }
                        else
                        {
                            //SDK.Execute("RRPANDORA_REFRESHSTATIONS");
                            SDK.Execute("load;rrpandora_list.skin");
                            SDK.Execute("CLLOAD;" + DPath + "Support_files\\station_list.txt");
                        }
                        SDK.Execute("CLFIND;" + _currentStationId);
                    }
                    catch (Exception err)
                    {
                            ToLog("Error with command RRPANDORA: " + err.Message);
                    }
                    result = ProcessCommandResults.CommandProcessedStayOnScreen;
					break;

                case "rrpandora_thumbsup":
                    ToLog(MYCMD[0] + " Command executed");
                    ThumbsUp_Click();
                    result = ProcessCommandResults.CommandProcessedStayOnScreen;
                    break;

                case "rrpandora_thumbsdown":
                    ToLog(MYCMD[0] + " Command executed");
                    ThumbsDown_Click();
                    if (SkipOnHate == "True") 
                        PlayInWinamp(musicBox.GetNextSong(false).AudioURL,true);
                    result = ProcessCommandResults.CommandProcessedStayOnScreen;
                    break;

                case "rrpandora_refreshstations":
                    ToLog(MYCMD[0] + " Command executed");
                    RefreshStations();
                    if (SDK.GetInfo("RRSCREEN").ToLower().Contains("rrpandora_list"))
                    {
                        SDK.Execute("CLLOAD;" + DPath + "support_files\\station_list.txt");
                        SDK.Execute("CLFIND;" + _currentStationId);
                    }
                    result = ProcessCommandResults.CommandProcessedStayOnScreen;
                    break;

				case "onsuspend":
                    ToLog(MYCMD[0] + " Command executed");
                    if (IsActive)
                    {
                        MyWinAmp.Stop();
                        StatusTimer.Enabled = false;
                        SongProgressTimer.Enabled = false;
                        IsResumingActive = true;
                    }
					break;

				case "onresume":
                    ToLog(MYCMD[0] + " Command executed");

                    //if (IsResumingActive == true)
                    //{
                        //IsActive = true;
                        //if (_isConnected)
                            //if (!AuthWorker.IsBusy)
                               // AuthWorker.RunWorkerAsync();
                    //}
                    //}
                    //if (ResumeLastPlayed == "True")
                    //{
                        //_hasControl = true;
                        //if (string.IsNullOrEmpty(_userName))
                            //SDK.ErrScrn("RRPandora", "Error with login", "Please verify your username and password in settings");
                        //else
                        //{
                            //if (!_hasSession)
                                //_isStartup = true;
                            //if (!ConnectionWorker.IsBusy)
                                //ConnectionWorker.RunWorkerAsync();
                           ////if (UseFlicker)
                                ////imageWorker.RunWorkerAsync();
                            //StatusTimer.Start();
                            //result = ProcessCommandResults.CommandProcessedStayOnScreen;
                            //Pandora_isPlaying = true;
                            //IsResumed = true;
                        //}
                    //}
					break;

				case "onexit":
					break;

                case "onsourcechange":
                    ToLog(MYCMD[0] + " Command executed");
                    if (SDK.GetInfo("ACTIVESOURCE") == "RRPandora")
                    {
                        // do nothing
                    }else if(SDK.GetInfo("ACTIVESOURCE").Length == 0)
                    {
                        //probably the start of a crashed rr, ignore
                    }else
                    {
                        //player.Stop();
                        //MyWinAmp.StopWinamp();
                        // set last resume to false
                    }
                    break;

                case "online":
                    ToLog(MYCMD[0] + " Command executed");
                    

                    //if (Pandora_isPlaying)
                    //{
                        //_hasControl = true;
                        //if (string.IsNullOrEmpty(_userName))
                            //SDK.ErrScrn("RRPandora", "Error with login", "Please verify your username and password in settings");
                        //else
                        //{
                            //if (!_hasSession)
                                //_isStartup = true;
                            //if (!ConnectionWorker.IsBusy)
                                //ConnectionWorker.RunWorkerAsync();
                            ////if (UseFlicker)
                                ////imageWorker.RunWorkerAsync();
                            //StatusTimer.Start();
                            //result = ProcessCommandResults.CommandProcessedStayOnScreen;
                            //Pandora_isPlaying = true;
                        //}
                    //}
					result = ProcessCommandResults.CommandProcessedStayOnScreen;
                    break;

                case "offline":
                    ToLog(MYCMD[0] + " Command executed");
                    _isConnected = false;
                    //StatusTimer.Enabled = false;
                   

                    if (!ConnectionWorker.IsBusy)
                        ConnectionWorker.RunWorkerAsync();
                    ConnectionCheckTimer.Enabled = true;
					result = ProcessCommandResults.CommandProcessedStayOnScreen;
                    break;

                case "onscreenchange":
                    // Set .AppName to our Visual
                    frm.GetType().InvokeMember("AppName", BindingFlags.SetProperty, null, frm, new object[] { VisuWindowName });
                    break;

                case "onclselclick":
                    ToLog(MYCMD[0] + " Command executed");
                    switch(SDK.GetInfo("RRSCREEN").ToLower())
                    {
                        case "rrpandora_list.skin":
                            PandoraMusicBox.Engine.Data.PandoraStation newPMBStation = null;
                            String newStationId = SDK.GetInfo("CLTEXT");
                            foreach (PandoraMusicBox.Engine.Data.PandoraStation station in musicBox.AvailableStations)
                            {
                                if (newStationId == station.Id)
                                    newPMBStation = station;

                            }
                            if (newPMBStation != null && newPMBStation != musicBox.CurrentStation)
                            {

                                musicBox.CurrentStation = newPMBStation;
                                if (File.Exists(DPath + "Support_Files\\LastPlayed_List.txt"))
                                {
                                    File.Delete(DPath + "Support_Files\\LastPlayed_List.txt");
                                }
                                using (StreamWriter writer = new StreamWriter(DPath + "Support_Files\\LastPlayed_List.txt", true))
                                {
                                    writer.WriteLine("0");
                                    writer.WriteLine("LST" + newStationId);
                                }

                                //PlayCurrentStation();

                                //PlayNext(false);
                                PlayInWinamp(musicBox.GetNextSong(false).AudioURL, true);
                                SaveToConfig(SettingNames.LastStationId, newStationId);
                            }
                            CMD = "";
                            result = ProcessCommandResults.CommandProcessedStayOnScreen;
                            break;

                        case "rrpandora_searchresults.skin":
                            pclient.CreateStationAsync(SDK.GetInfo("CLTEXT"));
                            SDK.Execute("CLOSE");
                            break;
                    }
                    
                    break;

                case "rrpandora_createstation":
                    ToLog(MYCMD[0] + " Command executed");
                    SDK.Execute("OSKTOCMD;NEWPANDORASTATION;RRPANDORA_STATIONNAMESET");
                    SDK.Execute("OSKTEXT;Enter the name of an artist or a song");
                    OSKText = "Enter the name of an artist or a song";
                    OSKTextResetTimer.Enabled = true;
                    break;

                case "rrpandora_deletestation":
                    ToLog(MYCMD[0] + " Command executed");
                    deleteStation(SDK.GetInfo("CLDESC"));
                    break;

                case "rrpandora_stationnameset":
                    ToLog(MYCMD[0] + " Command executed");
                    CreateStation_Click();
                    break;

                case "rrpandora_select":
                    ToLog(MYCMD[0] + " Command executed");
                    SDK.Execute("ONCLSELCLICK");
            
                    break;

                case "rrpandora_settings":
                    ToLog(MYCMD[0] + " Command executed");
                    if (File.Exists(DPath + "RRPandora_settings.xml"))
                    { 
                        File.Copy(DPath + "RRPandora_settings.xml", DPath + "RRPandora_settings.bak",true);
                    }
                    
                    SDK.Execute("LOAD;RRPANDORA_SETTINGS.SKIN");
                    PopulateSettingsIndicators();
                    result = ProcessCommandResults.CommandProcessedStayOnScreen;
                    break;

                case "rrpandora_cancelsettings":
                    ToLog(MYCMD[0] + " Command executed");
                    if (File.Exists(DPath + "RRPandora_settings.bak"))
                    {
                        File.Copy(DPath + "RRPandora_settings.bak", DPath + "RRPandora_settings.xml", true);
                    }
                    result = ProcessCommandResults.CommandProcessedStayOnScreen;
                    break;

                case "rrpandora_setsetting":
                    ToLog(MYCMD[0] + " Command executed");
                    if (MYCMD.GetUpperBound(0) == 1)
                    {
                        SetSetting(MYCMD[1]);
                    }
                    result = ProcessCommandResults.CommandProcessedStayOnScreen;
                break;

                case "rrpandora_setpassword":
                    XmlDocument xd = new XmlDocument();
                    xd.Load(DPath + "rrpandora_settings.xml");

                    XmlNode nod = xd.SelectSingleNode("/RRPandora/UserSettings/Password");
                    if (nod != null) {
	                    //nod.InnerText = SDK.GetInfo("=$RRPANDORA_PASSWORD$");
                        nod.InnerText = EncryptionHelper.EncryptString(SDK.GetInfo("=$RRPANDORA_PASSWORD$"), ENCRYPTION_PASSPHRASE);
                        HiddenPassword = new String('*', EncryptionHelper.EncryptString(SDK.GetInfo("=$RRPANDORA_PASSWORD$"), ENCRYPTION_PASSPHRASE).Length);
	                   _password = SDK.GetInfo("=$RRPANDORA_PASSWORD$");
                    }
                    // Save the Xml.
                    xd.Save(DPath + "rrpandora_settings.xml");
                    break;

                case "rrpandora_setusername":
                    XmlDocument xd1 = new XmlDocument();
                    xd1.Load(DPath + "rrpandora_settings.xml");

                    XmlNode nod1 = xd1.SelectSingleNode("/RRPandora/UserSettings/Username");
                    if (nod1 != null)
                    {
                        nod1.InnerText = SDK.GetInfo("=$RRPANDORA_USERNAME$");
                        _userName = SDK.GetInfo("=$RRPANDORA_USERNAME$");
                    }
                    // Save the Xml.
                    xd1.Save(DPath + "rrpandora_settings.xml");
                    break;

                case "vol+":
                case "vol-":
                    if (MYCMD[0].Equals("winamp", StringComparison.OrdinalIgnoreCase) || MYCMD[1].Equals("player", StringComparison.OrdinalIgnoreCase))
                        GetNewVolume = true;
                    break;

                case "visu":
                    if (MYCMD.Length == 2)
                    {
                        if (MYCMD[1] == "0")
                            MYCMD[1] = "false";
                        if (MYCMD[1] == "1")
                            MYCMD[1] = "true";

                        bool state = false;
                        if (bool.TryParse(MYCMD[1], out state) == true)
                        {
                            if (state == true && MyWinAmp.IsVisualRunning() == false)
                                MyWinAmp.Visual();
                            else if (state == false && MyWinAmp.IsVisualRunning() == true)
                                MyWinAmp.Visual();
                        }
                    }
                    else
                        MyWinAmp.Visual();

                    // clear command, so no further processing by RR
                    //CMD = "run;;;!Winamp Gen!AVS";
                    CMD = "";
                    result = ProcessCommandResults.CommandProcessedStayOnScreen;
                    break;
			}

            if (IsActive == true)
            {
                switch (MYCMD[0].ToLower())
                {
                    case "rrpandora_play":
                    case "play":
                        ToLog(MYCMD[0] + " Command executed");
                        if (MyWinAmp.enumWinampStatus == WinampStatusEnum.Playing)
                        {
                            //pause winamp instance
                            MyWinAmp.Pause();
                            StatusTimer.Enabled = false;
                            SongProgressTimer.Enabled = false;
                            RefreshTimer.Enabled = false;
                        }
                        else if(MyWinAmp.GetPlaylistCount() != 0)
                        {
                            MyWinAmp.Play();
                            StatusTimer.Enabled = true;
                            SongProgressTimer.Enabled = true;
                            RefreshTimer.Enabled = true;
                        }
                        CMD = "";
                        result = ProcessCommandResults.CommandProcessedStayOnScreen;
                        break;

                    case "rrpandora_nexttrack":
                    case "nexttrack":
                    case "next":
                    case "audionext":
                    case "rrnext":
                        ToLog(MYCMD[0] + " Command executed");
                        if (_currentStationCanSkip)
                        {
                            NextTrack();
                        }
                        else
                        {
                            SDK.ErrScrn("RRPandora", "Uh Oh", "Free Pandora accounts permit 6 skips per hour per station, for up to 12 total skips per day across all stations. The daily skip limit helps us prevent having to pay royalties on songs that are not being heard.");
                        }
                        CMD = "";
                        result = ProcessCommandResults.CommandProcessedStayOnScreen;
                        break;

                    case "rrpandora_prevtrack":
                    case "prevtrack":
                    case "prev":
                    case "audioprev":
                    case "rrprev":
                        ToLog(MYCMD[0] + " Command executed");
                        SDK.ErrScrn("RRPandora", "Command not executed", "Previous Track function does not exist in Pandora.");
                        //PreviousTrack();
                        CMD = "";
                        result = ProcessCommandResults.CommandProcessedStayOnScreen;
                        break;

                    case "customsource":
                        SDK.Execute("RRPANDORA");
                        CMD = "";
                        result = ProcessCommandResults.CommandProcessedStayOnScreen;
                        break;
                }
            }

            return (int)result;
		}

		/// <summary>
		/// This Function will be called with a requested label code and
		/// format specified at the skin file. Simply return any text to
		/// be displayed for the specified format.
		/// </summary>
		/// <param name="LBL"></param>
		/// <param name="FMT"></param>
		/// <returns></returns>
		public string ReturnLabel(ref string LBL, string FMT)
		{
			string s = "";

            switch (LBL.ToLower())
            {
                case "rrpandora_username":
                    s = _userName;
                    break;

                case "rrpandora_password":
                    s = HiddenPassword;
                    break;
            }

            if (IsActive == false)
                return s;


            // goofy but works
            int level;
            // If Winamp... sync EQ and Preamp
            if (SDK.GetUserVar("player").Equals("WINAMP", StringComparison.OrdinalIgnoreCase))
            {
                // 0 - 10 = bands
                // 11 eq enabled
                // 12 autoeq enabled

                level = WinampInterface.GetEqualizerBand("Winamp v1.x", EqAsk);
                MyWinAmp.SetEqualizerBand(EqAsk, level);

                // Set for next band				
                EqAsk++;
                if (EqAsk > 12)
                    EqAsk = 0;

                // EQEnabled
                //bool state = WinampInterface.GetEqualizerBand("Winamp v1.x", 11) != 0;
                //MyWinAmp.SetEqualizerBand(11, state?1:0);
                // AutoEQ
                //state = WinampInterface.GetEqualizerBand("Winamp v1.x", 12) != 0;
                //MyWinAmp.SetEqualizerBand(12, state ? 1 : 0);

                level = WinampInterface.GetVolume("Winamp v1.x");
                MyWinAmp.SetVolume(level);
            }
            else
            {
                // PLAYER VOLUME
                if (GetNewVolume && LBL.ToLower() != "vol;player")
                {
                    GetNewVolume = false;
                    string ss = SDK.GetInfo("vol;PLAYER");
                    if (int.TryParse(ss, out level))
                        MyWinAmp.SetVolume(level);
                }
            }

            


			switch (LBL.ToLower())
			{
				case "rrpandora_tracktitle":
                case "trackname":
                case "tagtitle":
                       s = _currentSongTitle;
                       LBL = "";
					break;

                case "rrpandora_trackartist":
                case "tagartist":

                        s = _currentSongArtist;
                        LBL = "";
                    break;

                case "rrpandora_trackalbum":
                case "tagalbum":

                        s = _currentSongAlbum;
                        LBL = "";
                    break;

                case "rrpandora_tracktime":
                case "tracktime":
                    s = _currentSongLength;
                    LBL = "";
                    break;

                case "rrpandora_currenttracktime":
                case "currenttracktime":
                    //s = player.Position.ToString();
                    s = _currentSongPosition;
                    LBL = "";
                    break;


                case "rrpandora_stationname":
                case "taggenre":
 
                        s = _currentStationName;
                        LBL = "";
                    break;

                case "status":
                    s = MyWinAmp.enumWinampStatus.ToString().Substring(0, 4).ToUpper();
                    if (s.Equals("PAUS"))
                        s = "PAUSE";
                    if (s == "STOP" & MyWinAmp.GetPlaylistCount() == 0)
                        s = "";

                    LBL = ""; // prevent further RR processing
                    break;

                case "playlist":
                    s = _currentStationName;

                    LBL = ""; // prevent further RR processing
                    break;

                case "kbps":
                    s = MyWinAmp.GetTrackInfo().iBitrate.ToString() + "Kbps";

                    LBL = ""; // prevent further RR processing
                    break;

                case "khz":
                    s = MyWinAmp.GetTrackInfo().iSampleRate.ToString() + "Khz";

                    LBL = ""; // prevent further RR processing
                    break;
			}

			return s;
		}

		// deprecaited DONT USE
		public string ReturnIndicator(string Ind)
		{
			return "";
		}

		/// <summary>
		/// This Function will be called with requested indicator code
		/// specified at the skin file. Simply return "True" or "False" to
		/// displayed the respective ON or OFF layer of the skin images.
		/// alternatively you can specify a path to a file to be displayed
		/// as the indicator specified. Return "False" to erase the image.
		/// ONLY return something else IF AND ONLY IF you process that code
		/// </summary>
		/// <param name="Ind"></param>
		/// <returns>"" for not processed</returns>
		public string ReturnIndicatorEx(ref string Ind)
		{
            string s = "";

            switch (Ind.ToLower())
            {
                case "rrpandora_debugmode":
                    s = DebugModeIndicator;
                    break;

                case "rrpandora_skiponhate":
                    s = SkipOnHateIndicator;
                    break;
            }

            if (IsActive == false)
                return s;

            switch (Ind.ToLower())
            {

                case "rrpandora_thumbsup":
                    s = ThumbsUpInd;
                    break;

           
                case "rrpandora_thumbsdown":
                    s = ThumbsDownInd;
                    break;

                

                case "rrpandora_canskip":
                    if (_currentStationCanSkip)
                    {
                        s = "True";
                    }
                    else
                    {
                        s = "False";
                    }
                    break;

                case "rrpandora_trackart":
                case "albumart":
                case "coverart":
                         s= MyCurrentTrackArt;

                         Ind = ""; // prevent further RR processing
                    break;


                    
       



            }
            return s;
		}

		/// <summary>
		/// This Sub will be called with an indicator code "CLICKED"
		/// specified at the skin file. This "event" so to speak can be used
		/// to toggle indicators or execute any code you desire when clicking
		/// on a specifig indicator in the skin. You can also modify IND and
		/// monitor the IND parameter as to detect/alter the behaviour of
		/// how RR will process the indicator code being clicked.
		/// </summary>
		/// <param name="IND"></param>
		public void IndicatorClick(ref string IND)
		{
			switch (IND.ToLower())
			{

				case "rrpandora_thumbsdown":
                    SDK.Execute("RRPANDORA_THUMBSDOWN");
					break;

                case "rrpandora_thumbsup":
                    SDK.Execute("RRPANDORA_THUMBSUP");
                    break;

                case "rrpandora_trackart":
                case "albumart":
                case "coverart":
                    LoadAlbumArt();
                    break;
			}
		}

		/// <summary>
		/// 
		/// </summary>
		/// <param name="SLD"></param>
		/// <returns>-1 for not processed</returns>
		public long ReturnSlider(ref string SLD)
		{
        
            if (IsActive == false)
                return -1;

			//return -1;

            switch (SLD.ToLower())
            {
                case "rrpandora_trackposition":
                case "songpos":
                    return ((long)CurrentSecs * (65536 / (long)TotalSecs));
            }

            return -1;

		}

		#endregion

		#region Logging

		[ComVisible(false)]
		static private void log(string message)
		{
			if (isAssemblyDebugBuild() == true)
			{
				SDK.DoLog(message);
			}
		}

		[ComVisible(false)]
		static private bool isAssemblyDebugBuild()
		{
			System.Reflection.Assembly assemb = System.Reflection.Assembly.GetExecutingAssembly();

			foreach (object att in assemb.GetCustomAttributes(false))
			{
				if (att.GetType() == System.Type.GetType("System.Diagnostics.DebuggableAttribute"))
				{
					return ((System.Diagnostics.DebuggableAttribute)att).IsJITTrackingEnabled;
				}
			}

			return false;
		}

		#endregion

		#region Private Methods
        
        private void LoadSettings()
        {

            //read settings file
            if (File.Exists(DPath + "RRPandora_Settings.xml"))
            {
                ToLog("Settings file loaded");
                SettingsXML.Load(DPath + "RRPandora_Settings.xml");
                XmlNodeList myItems = SettingsXML.SelectNodes("RRPandora/UserSettings");
                XmlNode myDetail = null;
                int i = 1;

                for (i = 1; i <= myItems.Count; i++)
                {
                    myDetail = myItems.Item(i - 1);
                    if ((myDetail != null))
                    {
                        try
                        {
                            DebugMode = myDetail.SelectSingleNode("DebugMode").InnerText;
                            ToLog("Debug mode setting found.  Debug set to " + DebugMode);
                        }
                        catch (Exception err)
                        {
             
                                ToLog("ERROR: Debug Mode Setting Not Found");
                            DebugMode= "False";
                        }
                        try
                        {
                            _userName = myDetail.SelectSingleNode("Username").InnerText;
                            ToLog("Username setting found.  Username set to " + _userName);
                        }
                        catch (Exception err)
                        {
                            
                                ToLog("ERROR: Username not found.");
                            _userName = null;
                        }
                        try
                        {
                            _encryptedPassword = myDetail.SelectSingleNode("Password").InnerText;
                            if (!String.IsNullOrEmpty(_encryptedPassword))
                            {
                                try
                                {
                                    _password = EncryptionHelper.DecryptString(_encryptedPassword, ENCRYPTION_PASSPHRASE);
                                    ToLog("Password found and decrypted");
                                }
                                catch (Exception ex)
                                {
                                    
                                        ToLog("Error during password decryption. - " + ex.Message);
                                }
                                HiddenPassword = new String('*', _encryptedPassword.Length);
                            }
                            try
                            {
                                SkipOnHate = myDetail.SelectSingleNode("SkipOnHate").InnerText;
                                ToLog("SkipOnHate setting found.  SkipOnHate set to " + SkipOnHate);
                            }
                            catch (Exception err)
                            {

                                ToLog("ERROR: SkipOnHate setting not found.  Using default False");
                                SkipOnHate = "False";
                                AddToConfig("User","SkipOnHate", "False");
                            }
                            
                        }
                        catch (Exception err)
                        {
                          
                                ToLog("ERROR: Password not found");
                            _password=null;
                        }
                    }
                }

                XmlNodeList mySystemSettings = SettingsXML.SelectNodes("RRPandora/SystemSettings");
                XmlNode myData = null;
                int s = 1;

                for (s = 1; s <= mySystemSettings.Count; s++)
                {
                    myData = mySystemSettings.Item(s - 1);
                    if ((myData != null))
                    {
                        try
                        {
                            _lastStationId = myData["LastStationID"].InnerText;
                            ToLog("Last Station ID setting found.  LastStationID is " + _lastStationId);
                        }
                        catch (Exception err)
                        {
                            
                                ToLog("ERROR: Last Station setting not found.");
                        }
                        try
                        {
                            ActiveList = myData["ActiveList"].InnerText;
                        }
                        catch (Exception err)
                        {
                            log("ERROR: Active list setting not found.  Using default");
                            ActiveList = "";
                            if (string.IsNullOrEmpty(ActiveList))
                                ActiveList = WebRadioRootList;
                        }
                        try
                        {
                            PlayName = myData["PlayName"].InnerText;
                        }
                        catch (Exception err)
                        {
                            log("ERROR: Play Name setting not found.  Using default");
                            PlayName = "";
                        }
                        try
                        {
                            PlayItem = myData["PlayItem"].InnerText;
                        }
                        catch (Exception err)
                        {
                            log("ERROR: Play Item setting not found.  Using default");
                            PlayItem = "";
                            if (PlayItem.StartsWith("!#") == true)
                                PlayItem = "";
                        }
                        try
                        {
                            if (myData["PlayState"].InnerText.ToLower() == "playing")
                            {
                                ShouldPlay = true;
                            }
                            else
                            {
                                ShouldPlay = false;
                            }
                        }
                        catch (Exception err)
                        {
                            ShouldPlay = false;
                        }
                    }
                }
                DeleteFromConfig("System", "LastResumePlayed");
            }
        }

        void SongProgressTimer_Tick(object sender, EventArgs e)
        {
            if (!_currentSongIsAdvertisement)
            {
                if (MyWinAmp.enumWinampStatus == WinampStatusEnum.Stopped || MyWinAmp.enumWinampStatus == WinampStatusEnum.Paused)
                {
                    SongProgressTimer.Stop();
                }
                else
                {
                    //SongTime = SongTime.AddSeconds(1);
                    //_currentSongPosition = SongTime.ToString("mm:ss");
                    //CurrentSecs++;

                    TimeSpan SongPos = TimeSpan.FromMilliseconds(MyWinAmp.iCurrentTrackPosition);
                    _currentSongPosition = string.Format("{0:D2}:{1:D2}",SongPos.Minutes, SongPos.Seconds);
                    CurrentSecs = SongPos.TotalSeconds;

                    TimeSpan SongLength = TimeSpan.FromMilliseconds(MyWinAmp.iCurrentTrackDuration);
                    _currentSongLength = string.Format("{0:D2}:{1:D2}", SongLength.Minutes, SongLength.Seconds);
                    TotalSecs = SongLength.TotalSeconds;

                }
            }
            //else
            //{
                //stop song progress title, start adwait for 30 seconds
                //StatusTimer.Stop();
                //SongProgressTimer.Stop();
                //AdWaitTimer.Start();
            //}
               
        }

        void RefreshTimer_Tick(object sender, EventArgs e)
        {
            if (SDK.GetInfo("RRSCREEN").ToLower().Contains("rrpandora_list"))
            {
                if (_isConnected)
                {
                    try
                    {
                        musicBox.AvailableStations = pio.GetStations(musicBox.User);
                        if (musicBox.AvailableStations.Count != int.Parse(SDK.GetInfo("CLMAX")))
                        {
                            SDK.Execute("RRPANDORA_REFRESHSTATIONS");
                            RefreshTimer.Enabled = false;
                        }
                    }
                    catch (Exception err)
                    {
                        //daily limit exceeded probably
                        SDK.ErrScrn("RRPandora", "Error Syncing New Station", "Daily activity maximum reached.  Consider purchasing the premium plan.");
                        ToLog("ERROR syncing new station: " + err.Message);
                    }
                }
            }
        }

        void OSKTextResetTimer_Tick(object sender, EventArgs e)
        {
            if(SDK.GetInfo("RRSCREEN").ToLower().Contains("osk"))
            {
                OSKText = SDK.GetInfo("OSKTEXT");
                if (OSKText != "Enter the name of an artist or a song")
                {
                    //get last letter of string
                    
                    SDK.Execute("OSKTEXT;" + OSKText.Substring(0,1));
                    OSKTextResetTimer.Enabled = false;
                }
            }
        }

        void ConnectionCheckTimer_Tick(object sender, EventArgs e)
        {
            if (IsConnectionAvailable() == true)
            {
                _waitHandle.Set();
                _isConnected = true;
                ConnectionCheckTimer.Enabled = false;
            }
        }

        void StatusTimer_Tick(object sender, EventArgs e)
        {
            try
            {
                if (SDK.GetInfo("ACTIVESOURCE").ToLower().Contains("pandora"))
                {
                    IsActive = true;
                }
                //check internet status
                if (_isConnected)
                    try
                    {
                        //_waitHandle.Set();
                        //if (_hasControl)
                        //{

                        
                        if (IsActive && !string.IsNullOrEmpty(_currentStationId) && MyWinAmp.enumWinampStatus == WinampStatusEnum.Stopped || MyWinAmp.enumWinampStatus == WinampStatusEnum.Paused)
                        {
                                //PlayNext(false);
                            PlayInWinamp(musicBox.GetNextSong(false).AudioURL, true);
                        }
                        MyWinAmp.SetRepeat(false);
                        MyWinAmp.SetShuffle(false);
                        if (SDK.GetInfo("=$HIDEPLAYER$").ToLower() == "true")
                            MyWinAmp.HideWinamp();

                        //}
                    }
                    catch (Exception err)
                    {
                        
                        ToLog(err.Message);
                    }
                //check playback status
                _currentStationId = musicBox.CurrentStation.Id;
                _currentStationName = musicBox.CurrentStation.Name;
                _currentStationCanSkip = musicBox.SkipHistory.CanSkip(musicBox.CurrentStation);
                _currentSongAlbum = musicBox.CurrentSong.Album;
                _currentSongAlbumArtURL = musicBox.CurrentSong.AlbumArtLargeURL;
                _currentSongAlbumDetailsURL = musicBox.CurrentSong.AlbumDetailsURL;
                _currentSongArtistArtURL = musicBox.CurrentSong.ArtistArtURL;
                _currentSongArtist = musicBox.CurrentSong.Artist;
                _currentSongIsAdvertisement = musicBox.CurrentSong.IsAdvertisement;
                _currentSongMusicId = musicBox.CurrentSong.MusicId;
                if (_isConnected)
                {
                    _currentSongTitle = musicBox.CurrentSong.Title;
                }
                else
                {
                    _currentSongTitle = "Connection interrupted.  Music will resume when connection re-established.";
                }
                _currentSongTrackToken = musicBox.CurrentSong.TrackToken;
                _currentSongRating = musicBox.CurrentSong.Rating;

                //check album art status


                //check artist art status
                if (albumStarted)
                {
                    alCnt++;
                    if (alCnt > 60)
                    {
                        albumclient.CancelAsync();
                        albumStarted = false;
                        albumDone = false;
                        //alCnt = 0;
                        //altType = 0;
                        //LoadAltArt(_currentSongArtist + "+" + _currentSongAlbum);
                    }
                }

                try
                {

                    if (albumDone)
                    {
                        albumDone = false;

                        if (tempALImage != null)
                        {
                            _currentSongAlbumArtImage = tempALImage;
                            _currentSongAlbumArtImage.Save(DPath + "Support_Files\\Track_Art.png");
                            //base.CF_setPictureImage("AlbumArtPicture", _currentSongAlbumArtImage);
                        }
                        else
                        {
                            _currentSongAlbumArtImage = Image.FromFile(DPath + "Support_Files\\defaultalbumart.png");
                            _currentSongAlbumArtImage.Save(DPath + "Support_Files\\Track_Art.png");
                        }
                        MyCurrentTrackArt = DPath + "Support_Files\\Track_Art.png";
                    }
        
                }
                catch (Exception err)
                {
                    
                    ToLog("error processing album art: " + err.Message);
                }

                try
                {
                    //set thumbs up/down indicators based on current track
                    if (_currentSongRating == PandoraMusicBox.Engine.PandoraRating.Love)
                    {
                        ThumbsDownInd = "False";
                        ThumbsUpInd = "True";
                    }
                    else if (_currentSongRating == PandoraMusicBox.Engine.PandoraRating.Hate)
                    {
                        ThumbsDownInd = "True";
                        ThumbsUpInd = "False";
                    }
                    else
                    {
                        //ThumbsDownInd = "False";
                        //ThumbsUpInd = "False";
                    }
                }
                catch (Exception err)
                {
                   
                    ToLog("error handling thumbs up/down status: " + err.Message);
                }
            }
            catch (Exception err)
            {
               
                    ToLog(err.Message);
            }
        }

        void AddToConfig(string NodeType, string NodeName, string NodeValue)
        {
            try
            {
                XmlDocument doc = new XmlDocument();
                doc.Load(DPath + "rrpandora_settings.xml");

                //get the last node in NodeType
                XmlNodeList myItems = doc.SelectNodes("RRPandora/"+ NodeType + "Settings");
                XmlNode myDetail = null;

                myDetail = myItems.Item(myItems.Count - 1).LastChild;

                //last node is here
                string LastNode = myDetail.Name;
                XmlElement root = doc.DocumentElement;
                XmlNodeList nodeList;

                    nodeList = doc.GetElementsByTagName(LastNode);

                foreach (XmlNode node in nodeList)
                {
                    //Can avoid this if there is only one occurrence in the XML.
                    //if (node.OuterXml.Contains("Password"))
                    //{
                        XmlElement newElement = doc.CreateElement(NodeName);
                        XmlText txtVal = doc.CreateTextNode(NodeValue);
                        XmlNode parent1 = node.ParentNode;
                        parent1.AppendChild(newElement);
                        parent1.LastChild.AppendChild(txtVal);
                    //}
                }
                doc.Save(DPath + "rrpandora_settings.xml");
            }
            catch (Exception err)
            {
                MessageBox.Show(err.Message);
            }
        }

        void SaveToConfig(SettingNames NewSetting, string TheSetting)
        {
            switch (NewSetting)
            {
                case SettingNames.LastStationId:
                    XmlDocument xd4 = new XmlDocument();
                    xd4.Load(DPath + "rrpandora_settings.xml");
                    XmlNode nod4 = xd4.SelectSingleNode("/RRPandora/SystemSettings/LastStationID");
                    if (nod4 != null)
                    {
                        nod4.InnerText = TheSetting;
                        //nod.ChildNodes(0).InnerText = TheSetting;
                    }
                    // Save the Xml.
                    xd4.Save(DPath + "RRPandora_settings.xml");
                    break;
                case SettingNames.Username:
                    XmlDocument xd1 = new XmlDocument();
                    xd1.Load(DPath + "rrpandora_settings.xml");
                    XmlNode nod1 = xd1.SelectSingleNode("/RRPandora/UserSettings/Username");
                    if (nod1 != null)
                    {
                        nod1.InnerText = TheSetting;
                        //nod.ChildNodes(0).InnerText = TheSetting;
                        _userName = TheSetting;
                    }
                    // Save the Xml.
                    xd1.Save(DPath + "RRPandora_settings.xml");
                    break;
                case SettingNames.Password:
                    XmlDocument xd2 = new XmlDocument();
                    xd2.Load(DPath + "rrpandora_settings.xml");
                    XmlNode nod2 = xd2.SelectSingleNode("/RRPandora/UserSettings/Password");
                    if (nod2 != null)
                    {
                        nod2.InnerText = TheSetting;
                        //nod.ChildNodes(0).InnerText = TheSetting;
                        _password = TheSetting;
                    }
                    // Save the Xml.
                    xd2.Save(DPath + "RRPandora_settings.xml");
                    break;
                case SettingNames.SkipOnHate:
                    XmlDocument xd3 = new XmlDocument();
                    xd3.Load(DPath + "rrpandora_settings.xml");
                    XmlNode nod3 = xd3.SelectSingleNode("/RRPandora/UserSettings/SkipOnHate");
                    if (nod3 != null)
                    {
                        nod3.InnerText = TheSetting;
                        //nod.ChildNodes(0).InnerText = TheSetting;
                        SkipOnHate = TheSetting;
                    }
                    // Save the Xml.
                    xd3.Save(DPath + "RRPandora_settings.xml");
                    break;
                case SettingNames.ActiveList:
                    XmlDocument xd5 = new XmlDocument();
                    xd5.Load(DPath + "rrPandora_settings.xml");
                    XmlNode nod5 = xd5.SelectSingleNode("/RRPandora/SystemSettings/ActiveList");
                    if (nod5 != null)
                    {
                        nod5.InnerText = TheSetting;
                        //nod.ChildNodes(0).InnerText = TheSetting;
                        ActiveList = TheSetting;
                    }
                    // Save the Xml.
                    xd5.Save(DPath + "RRPandora_settings.xml");
                    break;
                case SettingNames.PlayName:
                    XmlDocument xd6 = new XmlDocument();
                    xd6.Load(DPath + "rrPandora_settings.xml");
                    XmlNode nod6 = xd6.SelectSingleNode("/RRPandora/SystemSettings/PlayName");
                    if (nod6 != null)
                    {
                        nod6.InnerText = TheSetting;
                        //nod.ChildNodes(0).InnerText = TheSetting;
                        PlayName = TheSetting;
                    }
                    // Save the Xml.
                    xd6.Save(DPath + "RRPandora_settings.xml");
                    break;
                case SettingNames.PlayItem:
                    XmlDocument xd7 = new XmlDocument();
                    xd7.Load(DPath + "rrPandora_settings.xml");
                    XmlNode nod7 = xd7.SelectSingleNode("/RRPandora/SystemSettings/PlayItem");
                    if (nod7 != null)
                    {
                        nod7.InnerText = TheSetting;
                        //nod.ChildNodes(0).InnerText = TheSetting;
                        PlayItem = TheSetting;
                    }
                    // Save the Xml.
                    xd7.Save(DPath + "RRPandora_settings.xml");
                    break;
                case SettingNames.PlayState:
                    XmlDocument xd8 = new XmlDocument();
                    xd8.Load(DPath + "rrPandora_settings.xml");
                    XmlNode nod8 = xd8.SelectSingleNode("/RRPandora/SystemSettings/PlayState");
                    if (nod8 != null)
                    {
                        nod8.InnerText = TheSetting;
                        //nod.ChildNodes(0).InnerText = TheSetting;
                        if (TheSetting.ToLower() == "playing")
                        {
                            ShouldPlay = true;
                        }
                        else
                        {
                            ShouldPlay = false;
                        }

                    }
                    // Save the Xml.
                    xd8.Save(DPath + "RRPandora_settings.xml");
                    break;
            }

        }

        void DeleteFromConfig(string NodeType, string NodeName)
        {
            //this function removed obsolete nodes silently
            XmlDocument doc = new XmlDocument();
            doc.Load(DPath + "rrpandora_settings.xml");

            XmlNode t = doc.SelectSingleNode("RRPandora/" + NodeType + "Settings/" + NodeName);
            try
            {
                t.ParentNode.RemoveChild(t);
            }
            catch
            {
                //exception if setting doesnt exist, do nothing
            }

            doc.Save(DPath + "rrpandora_settings.xml");

        }

        Boolean IsConnectionAvailable()
        {
            System.Uri url = new System.Uri("http://www.google.com/");
            System.Net.WebRequest req;
            req = System.Net.WebRequest.Create(url);
            System.Net.WebResponse resp;

            try
            {
                resp = req.GetResponse();
                resp.Close();
                req = null;
                return true;
            }
            catch (Exception err)
            {
                req = null;
                return false;
            }
        }

        void ToLog(string TheMessage)
        {
            if (DebugMode == "True")
            {
                StreamWriter DebugLog;
                if (!File.Exists(DPath + "RRPandora_debug.txt"))
                {
                    DebugLog = new StreamWriter(DPath + "RRPandora_debug.txt");
                }
                else
                {
                    DebugLog = File.AppendText(DPath + "RRPandora_debug.txt");
                }

                // Write to the file:
                DebugLog.WriteLine(DateTime.Now + "-->" + TheMessage);

                // Close the stream:
                DebugLog.Close();
            }
        }

        private void RefreshStations()
        {
           
                ToLog("refresh stations method");
            if (_success)
            {
                int curpos = 0;
                try
                {
                    musicBox.AvailableStations = pio.GetStations(musicBox.User);
                    //musicBox.AvailableStations.Sort();
                    //SDK.Execute("CLCLEAR;ALL");

                    StreamWriter stationlist = new StreamWriter(DPath + "Support_Files\\station_list.txt",false);
                    //int x = 0;

                    stationlist.WriteLine("0");
                    
                        ToLog("avail station count = " + musicBox.AvailableStations.Count.ToString());
  
                    foreach (PandoraMusicBox.Engine.Data.PandoraStation station in musicBox.AvailableStations)
                    {
                        //SDK.Execute("CLADD;" + station.Id + ";" + station.Name);
                        stationlist.WriteLine("LST" + station.Id + "||" + station.Name);
                    }
                    //SDK.Execute("CLSAVE;" + DPath + "Support_Files\\station_list.txt");
                    stationlist.Close();
                    SelectStation(musicBox.CurrentStation.Id);

                    _playHandle.Set();
                }
                catch (PandoraMusicBox.Engine.PandoraException e)
                {
                   
                        ToLog(e.Message);
                }

            }

        }

        private void SelectStation(string stationID)
        {
            _playHandle.Set();
        }


        private void PlayInWinamp(string playitem, bool shouldPlay)
        {
            if (!string.IsNullOrEmpty(playitem))
            {
                this.MyWinAmp.ClearPlaylist();
                if (!playitem.Contains("://"))
                {
                    this.MyWinAmp.EnqueueTrack(playitem);
                }
                else
                {
                    this.MyWinAmp.EnqueueTrack(playitem);
                }
                if (this.MyWinAmp.GetPlaylistCount() > 0)
                {
                    if (shouldPlay)
                    {
                        this.MyWinAmp.Play();
                    }
                    this.PlayItem = playitem;
                }
                else
                {
                    this.MyWinAmp.Stop();
                    this.PlayItem = "!#1";
                    log("ERROR: Bad URL or file in playlist");
                }




                _currentStationId = musicBox.CurrentStation.Id;
                _currentStationName = musicBox.CurrentStation.Name;
                _currentStationCanSkip = musicBox.SkipHistory.CanSkip(musicBox.CurrentStation);
                _currentSongAlbum = musicBox.CurrentSong.Album;
                _currentSongAlbumArtURL = musicBox.CurrentSong.AlbumArtLargeURL;
                _currentSongAlbumDetailsURL = musicBox.CurrentSong.AlbumDetailsURL;
                _currentSongArtistArtURL = musicBox.CurrentSong.ArtistArtURL;
                _currentSongArtist = musicBox.CurrentSong.Artist;
                _currentSongIsAdvertisement = musicBox.CurrentSong.IsAdvertisement;
                _currentSongMusicId = musicBox.CurrentSong.MusicId;
                _currentSongTitle = musicBox.CurrentSong.Title;
                _currentSongTrackToken = musicBox.CurrentSong.TrackToken;
                _currentSongRating = musicBox.CurrentSong.Rating;
                CurrentSongLength = musicBox.CurrentSong.Length;
                //_currentSongLength = new DateTime(CurrentSongLength.Ticks).ToString("mm:ss");
                //solve for total seconds for progress bar
                //TotalSecs = CurrentSongLength.TotalSeconds;
                LoadAlbumArt();
                LoadArtistArt();
                SongProgressTimer.Start();

                ToLog("PlayNext: " + _currentStationName);
                if (_currentSongRating == PandoraMusicBox.Engine.PandoraRating.Love)
                {
                    ThumbsUpInd = "True";
                }
                else
                {
                    ThumbsUpInd = "False";
                }
                if (_currentSongRating == PandoraMusicBox.Engine.PandoraRating.Hate)
                {
                    ThumbsDownInd = "True";
                }
                else
                {
                    ThumbsDownInd = "False";
                }
                if (_currentSongRating == PandoraMusicBox.Engine.PandoraRating.Unrated)
                {
                    ThumbsUpInd = "False";
                    ThumbsUpInd = "False";
                }
            }


        }




        private void PlayNext(bool isSkip)
        {

            if (!_isConnected)


                if (isSkip && !musicBox.CanSkip())
                    return;


            

            //CF_setButtonOff("ThumbsDown");
            //CF_setButtonOff("ThumbsUp");
            if (musicBox.CurrentStation == null)
                SDK.ErrScrn("RRPandora", "Error Loading Station", "Please select a station first.");
            else
            {
                SongTime = new DateTime(2010, 1, 18, 00, 00, 00);
                _currentSongPosition = "00:00";
                CurrentSecs = 0;
                //player.Open(musicBox.GetNextSong(isSkip));
                //player.Play();

            

                _currentStationId = musicBox.CurrentStation.Id;
                _currentStationName = musicBox.CurrentStation.Name;
                _currentStationCanSkip = musicBox.SkipHistory.CanSkip(musicBox.CurrentStation);
                _currentSongAlbum = musicBox.CurrentSong.Album;
                _currentSongAlbumArtURL = musicBox.CurrentSong.AlbumArtLargeURL;
                _currentSongAlbumDetailsURL = musicBox.CurrentSong.AlbumDetailsURL;
                _currentSongArtistArtURL = musicBox.CurrentSong.ArtistArtURL;
                _currentSongArtist = musicBox.CurrentSong.Artist;
                _currentSongIsAdvertisement = musicBox.CurrentSong.IsAdvertisement;
                _currentSongMusicId = musicBox.CurrentSong.MusicId;
                _currentSongTitle = musicBox.CurrentSong.Title;
                _currentSongTrackToken = musicBox.CurrentSong.TrackToken;
                _currentSongRating = musicBox.CurrentSong.Rating;
                 CurrentSongLength = musicBox.CurrentSong.Length;
                _currentSongLength = new DateTime(CurrentSongLength.Ticks).ToString("mm:ss");
                //solve for total seconds for progress bar
                TotalSecs = CurrentSongLength.TotalSeconds;
                LoadAlbumArt();
                LoadArtistArt();
                SongProgressTimer.Start();
                
                    ToLog("PlayNext: " + _currentStationName);
                if (_currentSongRating == PandoraMusicBox.Engine.PandoraRating.Love)
                {
                    ThumbsUpInd = "True";
                }
                else
                {
                    ThumbsUpInd = "False";
                }
                if (_currentSongRating == PandoraMusicBox.Engine.PandoraRating.Hate)
                {
                    ThumbsDownInd = "True";
                }
                else
                {
                    ThumbsDownInd = "False";
                }
                if (_currentSongRating == PandoraMusicBox.Engine.PandoraRating.Unrated)
                {
                    ThumbsUpInd = "False";
                    ThumbsUpInd = "False";
                }

            }


        }

        private void PlayPause()
        {
           
                ToLog("PlayPause");

            //if (player.IsPlaying())
            //{
             //   player.Stop();
             //   Pandora_isPlaying = false;
                //CF_setPlayPauseButton(true, 0);
            //}
            //else
            //{
            //    player.Play();
             //   Pandora_isPlaying = true;
                //CF_setPlayPauseButton(false, 0);
            //}

        }

        private void PreviousTrack()
        {
            
                ToLog("PreviousTrack");
        }

        private void NextTrack()
        {
           
                ToLog("Next Track");
            //PlayNext(false);
                PlayInWinamp(musicBox.GetNextSong(true).AudioURL, true);
        }

        void deleteStation(string stationname)
        {
            string stationid = "";

            if (stationname == _currentStationName)
            {
                MyWinAmp.Stop();
                //delete last station info
                SaveToConfig(SettingNames.LastStationId, "");
            }

            foreach (PandoraMusicBox.Engine.Data.PandoraStation station in musicBox.AvailableStations)
            {
                if (station.Name == stationname)
                    stationid = station.Id;
            }
            pclient.RemoveStationAsync(stationid);

            SDK.Execute("RRPANDORA_REFRESHSTATIONS");
        }


        private void ThumbsUp_Click()
        {
           
                ToLog("Thumbs Up");
            if (musicBox.CurrentSong == null)
                return;
            if (musicBox.CurrentSong.Rating == PandoraMusicBox.Engine.PandoraRating.Love)
            {
                ThumbsUpInd = "True";
                ThumbsDownInd = "False";
                return;
            }
          SubmitFeedback(musicBox.CurrentSong, PandoraMusicBox.Engine.PandoraRating.Love);

          ThumbsUpInd = "True";
          ThumbsDownInd = "False";
        }

        private void ThumbsDown_Click()
        {
          
                ToLog("Thumbs Down");
            if (musicBox.CurrentSong == null)
                return;
            if (musicBox.CurrentSong.Rating == PandoraMusicBox.Engine.PandoraRating.Hate)
            {
                ThumbsDownInd = "False";
                ThumbsUpInd = "True";
            }
            SubmitFeedback(musicBox.CurrentSong, PandoraMusicBox.Engine.PandoraRating.Hate);

            ThumbsDownInd = "True";
            ThumbsUpInd = "False";

        }

        private void SubmitFeedback(PandoraMusicBox.Engine.Data.PandoraSong song, PandoraMusicBox.Engine.PandoraRating rating)
        {
            
                ToLog("submit feedback method");



            if (!_success)
                return;

            if (song == null)
                return;

            //if (rating == PandoraMusicBox.Engine.PandoraRating.Hate)
            //{
              //  CFDialogParams dialogParams = new CFDialogParams();
                //dialogParams.displaytext = "Are you sure you want to dislike this song?";
                //DialogResult dialogResult = CF_displayDialog(CF_Dialogs.YesNo, dialogParams);

//                if (dialogResult != DialogResult.OK)
  //                  return;
   //         }

            //if (rating == PandoraMusicBox.Engine.PandoraRating.Hate)
                //CF_setButtonOn("ThumbsDown");
            //else
               // CF_setButtonOn("ThumbsUp");

            musicBox.RateSong(song, rating);
        }

        private void CreateStation_Click()
        {
            try
            {
                    pclient.SearchAsync(SDK.GetInfo("=$NEWPANDORASTATION$"));
              }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }


        }

        public void LoadAlbumArt()
        {

            try
            {

                tempALImage = null;
                if (_isConnected)
                {
                    if (!string.IsNullOrEmpty(_currentSongAlbumArtURL))
                    {
                        MyCurrentTrackArt = "False";
                        albumStarted = true;
                        albumDone = false;
                        _albumStartDate = DateTime.Now;
                        albumclient.DownloadDataAsync(new Uri(_currentSongAlbumArtURL, UriKind.Absolute));

                    }
                }
            }
            catch (Exception exception)
            {
              
                    ToLog(exception.Message);
            }

        }
        public void LoadArtistArt()
        {

            try
            {
                tempARImage = null;
                if (_isConnected)
                {
                    if (!string.IsNullOrEmpty(_currentSongArtistArtURL))
                    {

                        artistStarted = true;
                        artistDone = false;
                        _artistStartDate = DateTime.Now;
                        //    artistclient.DownloadDataAsync(new Uri(_currentSongArtistArtURL, UriKind.Absolute));
                    }
                }
            }
            catch (Exception exception)
            {
              
                    ToLog(exception.Message);
            }
        }

        void pclient_CreateStationComplete(object sender, EventArgs<Station> e)
        {
            //CF_systemCommand(CF_Actions.HIDEINFO);
            RefreshStations();
            SDK.Execute("RRPANDORA_REFRESHSTATIONS");
            _station.SelectStation(e.Value.StationId);

        }

        void pclient_SearchComplete(object sender, EventArgs<List<SearchResult>> e)
        {
            //CF_systemCommand(CF_Actions.HIDEINFO);

            if (e.Value == null || e.Value.Count == 0)
                SDK.ErrScrn("RRPandora", "", "No results found.");
            //CF_displayMessage("No results found.");
            else
            {
                ShowSearchResults(e.Value);
                RefreshTimer.Enabled = true;
            }

        }

        private void ShowSearchResults(List<SearchResult> searchResults)
        {


            if (searchResults == null || searchResults.Count == 0)
                return;

            searchResults.Sort(delegate(SearchResult searchResult1, SearchResult searchResult2)
            {
                if (searchResult1.SearchResultType == searchResult2.SearchResultType)
                    return 0;
                else if (searchResult1.SearchResultType == SearchResultTypes.Artist &&
                            searchResult2.SearchResultType == SearchResultTypes.Song)
                    return -1;
                else if (searchResult1.SearchResultType == SearchResultTypes.Song &&
                            searchResult2.SearchResultType == SearchResultTypes.Artist)
                    return 1;
                else
                    return 0; //Shouldn't happen
            });


            SDK.Execute("MENU;RRPandora_SearchResults.skin");
            SDK.Execute("CLCLEAR;ALL");
            //CFControls.CFListViewItem[] listItems = new CFControls.CFListViewItem[searchResults.Count];

            for (int i = 0; i < searchResults.Count; i++)
            {
                SDK.Execute("CLADD;" + searchResults[i].MusicId + ";" + searchResults[i].ResultText);
                //listItems[i] = new CFControls.CFListViewItem(searchResults[i].ResultText, searchResults[i].MusicId, 0, false, searchResults[i] as object);
            }

            //CFDialogParams dialogParams = new CFDialogParams();
            //CFDialogResults dialogResults = new CFDialogResults();
            //dialogParams.displaytext = "Choose a result from the list to create a station.";
            //dialogParams.listitems = listItems;

            //DialogResult dialogResult = CF_displayDialog(CF_Dialogs.FileBrowser, dialogParams, dialogResults);

            //if (dialogResult != DialogResult.OK)
                //return;

            //pclient.CreateStationAsync(SDK.GetInfo("CLDESC"));
        }

        private void PopulateSettingsIndicators()
        {
            if (DebugMode == "True")
            {
                DebugModeIndicator = SDK.GetInfo("=$SKINPATH$") + "RRPandora_settingsOn.png";
            }
            else
            {
                DebugModeIndicator = SDK.GetInfo("=$SKINPATH$") + "RRPandora_settingsOff.png";
            }

            if (SkipOnHate == "True")
            {
                SkipOnHateIndicator = SDK.GetInfo("=$SKINPATH$") + "RRPandora_settingsOn.png";
            }
            else
            {
                SkipOnHateIndicator = SDK.GetInfo("=$SKINPATH$") + "RRPandora_settingsOff.png";
            }
        }

        private string SetSetting(string ChangedSetting)
        {
            switch (ChangedSetting.ToLower())
            {
                case "debugmode":
                    XmlDocument xd = new XmlDocument();
                    xd.Load(DPath + "RRPandora_settings.xml");

                    XmlNode nod = xd.SelectSingleNode("/RRPandora/UserSettings/DebugMode");
                    if (nod != null)
                    {
                        if (DebugMode == "True")
                        {
                            nod.InnerText = "False";
                            DebugMode = "False";
                            DebugModeIndicator = SDK.GetInfo("=$SKINPATH$") + "RRPandora_settingsOff.png";
                        }
                        else
                        {
                            nod.InnerText = "True";
                            DebugMode = "True";
                            DebugModeIndicator = SDK.GetInfo("=$SKINPATH$") + "RRPandora_settingsOn.png";
                        }
                    }
                    // Save the Xml.
                    xd.Save(DPath + "rrpandora_settings.xml");
                    break;
                case "username":
                    SDK.Execute("OSKTOCMD;RRPANDORA_USERNAME;RRPANDORA_SETUSERNAME");
                    break;
                case "password":
                    SDK.Execute("OSKTOCMD;RRPANDORA_PASSWORD;RRPANDORA_SETPASSWORD");
                    break;
                case "skiponhate":
                    XmlDocument xd1 = new XmlDocument();
                    xd1.Load(DPath + "RRPandora_settings.xml");

                    XmlNode nod1 = xd1.SelectSingleNode("/RRPandora/UserSettings/SkipOnHate");
                    if (nod1 != null)
                    {
                        if (SkipOnHate == "True")
                        {
                            nod1.InnerText = "False";
                            SkipOnHate = "False";
                            SkipOnHateIndicator = SDK.GetInfo("=$SKINPATH$") + "RRPandora_settingsOff.png";
                        }
                        else
                        {
                            nod1.InnerText = "True";
                            SkipOnHate = "True";
                            SkipOnHateIndicator = SDK.GetInfo("=$SKINPATH$") + "RRPandora_settingsOn.png";
                        }
                    }
                    // Save the Xml.
                    xd1.Save(DPath + "rrpandora_settings.xml");
                    break;

                default:
                    break;
                //do nothing
            }
            LoadSettings();
            return "";
        }

        private void ShowDetails(string _artist)
        {

            try
            {
                if (_isConnected)
                {
                    string urlstring = artistInfoURL + _artist.Replace(' ', '+');
                    infoclient.DownloadDataAsync(new Uri(urlstring, UriKind.Absolute));
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }


        }


		#endregion

        #region Events

        void imageWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            //FimageCount = FlickerImages.Count;
            //imagesComplete = true;

        }

        void imageWorker_DoWork(object sender, DoWorkEventArgs e)
        {
            //FS.SearchString = FlickerSearchTerm;
            //FS.SearchItems = FlickerItems;
            //FlickerImages = FS.getimages();

        }

        void albumclient_DownloadDataCompleted(object sender, DownloadDataCompletedEventArgs e)
        {
            try
            {
                if (!e.Cancelled)
                {
                    Stream s = new MemoryStream(e.Result);
                    tempALImage = new Bitmap(s);
                    albumStarted = false;
                    albumDone = true;
                }
            }
            catch (Exception err)
            {
              
                    ToLog("error with album client handler: " + err.Message);
            }
        }

        void artistclient_DownloadProgressChanged(object sender, DownloadProgressChangedEventArgs e)
        {
            artistValue = e.ProgressPercentage;

            if ((DateTime.Now - _artistStartDate).Seconds > 0)
            {

                double kbPerSecond = (e.BytesReceived / 1000) / (DateTime.Now - _artistStartDate).Seconds;
                double remainingTimeSeconds = (((e.TotalBytesToReceive - e.BytesReceived) / 1000) / kbPerSecond);
                string remainingTimeDisplay = string.Empty;
                if (remainingTimeSeconds > 3600)
                {
                    remainingTimeDisplay += ((int)(remainingTimeSeconds) / 3600).ToString("n0") + " hours, ";
                    remainingTimeSeconds %= 3600;
                }
                if (remainingTimeSeconds > 60)
                {
                    remainingTimeDisplay += ((int)(remainingTimeSeconds) / 60).ToString("n0") + " minutes, ";
                    remainingTimeSeconds %= 60;
                }
                remainingTimeDisplay += ((int)remainingTimeSeconds).ToString("n0") + " seconds remaining";
                artistStatusText = (e.BytesReceived / 1000).ToString("n0") + " bytes received of " + (e.TotalBytesToReceive / 1000).ToString("n0") + ": " + e.ProgressPercentage.ToString() + "% at " + kbPerSecond.ToString("n0") + "kb/s - " + remainingTimeDisplay;
            }

        }

        void artistclient_DownloadDataCompleted(object sender, DownloadDataCompletedEventArgs e)
        {
            if (!e.Cancelled)
            {


                Stream s = new MemoryStream(e.Result);
                tempARImage = new Bitmap(s);
                artistStarted = false;
                artistDone = true;
            }
        }

        void infoclient_DownloadDataCompleted(object sender, DownloadDataCompletedEventArgs e)
        {
            if (!e.Cancelled)
            {
                scrpos = 0;
                string imageURl = "";
                string bio = "";

                Stream s = new MemoryStream(e.Result);
                XmlDocument infoDoc = new XmlDocument();
                infoDoc.Load(s);
                XmlNodeList infoItems = infoDoc.GetElementsByTagName("artistExplorer");
                imageURl = infoItems.Item(0).Attributes["artUrl"].Value.ToString();

                infoItems = infoDoc.GetElementsByTagName("bio");
                bio = infoItems.Item(0).InnerXml;



                location = 1;
                //this.CF3_initSection("Details");



                string str1 = @"<html><head><title>Artist Info</title></head><body  style='background-color:Black; color:White'><p><img src='";
                string str2 = @"' width='200' height='200' align='left' alt='artist' style='margin-right:10px; margin-bottom:3px;' />";
                string str3 = @"</p></body></html>";
                string htmlstr = str1 + imageURl + str2 + bio + str3;
                //wpnl = panelArray[0];
                wb.Dock = DockStyle.Fill;
                //wpnl.BackColor = Color.Black;
                wb.ScrollBarsEnabled = false;
                wb.ScriptErrorsSuppressed = true;
                //MessageBox.Show(_currentSongAlbumDetailsURL);
                wb.DocumentText = htmlstr;
                //wpnl.Controls.Add(wb);

            }
        }

        void albumclient_DownloadProgressChanged(object sender, DownloadProgressChangedEventArgs e)
        {
            albumValue = e.ProgressPercentage;

            if ((DateTime.Now - _albumStartDate).Seconds > 0)
            {

                double kbPerSecond = (e.BytesReceived / 1000) / (DateTime.Now - _albumStartDate).Seconds;
                double remainingTimeSeconds = (((e.TotalBytesToReceive - e.BytesReceived) / 1000) / kbPerSecond);
                string remainingTimeDisplay = string.Empty;
                if (remainingTimeSeconds > 3600)
                {
                    remainingTimeDisplay += ((int)(remainingTimeSeconds) / 3600).ToString("n0") + " hours, ";
                    remainingTimeSeconds %= 3600;
                }
                if (remainingTimeSeconds > 60)
                {
                    remainingTimeDisplay += ((int)(remainingTimeSeconds) / 60).ToString("n0") + " minutes, ";
                    remainingTimeSeconds %= 60;
                }
                remainingTimeDisplay += ((int)remainingTimeSeconds).ToString("n0") + " seconds remaining";
                albumStatusText = (e.BytesReceived / 1000).ToString("n0") + " bytes received of " + (e.TotalBytesToReceive / 1000).ToString("n0") + ": " + e.ProgressPercentage.ToString() + "% at " + kbPerSecond.ToString("n0") + "kb/s - " + remainingTimeDisplay;
            }

        }

        void AuthWorker_DoWork(object sender, DoWorkEventArgs e)
        {

            try
            {
                Thread.Sleep(1000);
                // if we have no login credentials, prompt the user
                if (_userName == string.Empty)
                {
                    SDK.ErrScrn("RRPandora", "Credential Error", "No credentials found");
                }
                else
                {

                    // otherwise try to login, and if failed prompt the user
                
                        ToLog("Attempting to login with saved credentials...");
                    try
                    {
                        _success = musicBox.Login(_userName, _password);
                    }
                    catch (PandoraMusicBox.Engine.PandoraException ex)
                    {
                        
                            ToLog("Error Attempting to login." + ex.Message);
                    }

                }
            }
            catch (Exception ex)
            {
              
                    ToLog("Error Attempting to login." + ex.Message);
            }
        }

        void AuthWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            int errmsg = 0;
            try
            {
                if (_success)
                {
                    errmsg = 1;
                    //player.PlaybackEvent += new DirectShowPlayer.DirectShowEventHandler(player_PlaybackEvent);
                    errmsg = 2;
                    if (_lastStationId != "")
                    {
                        foreach (PandoraMusicBox.Engine.Data.PandoraStation station in musicBox.AvailableStations)
                        {
                            if (station.Id == _lastStationId)
                                musicBox.CurrentStation = station;
                        }
                        errmsg = 3;
                    }
                    else
                    {

                        foreach (PandoraMusicBox.Engine.Data.PandoraStation station in musicBox.AvailableStations)
                        {
                            if (musicBox.SkipHistory.CanSkip(station))
                            {
                                musicBox.CurrentStation = station;
                                break;
                            }
                        }
                        errmsg = 4;
                    }
                    errmsg = 4;
                    _currentStationName = musicBox.CurrentStation.Name;
                    errmsg = 5;
                    _currentStationId = musicBox.CurrentStation.Id;
                    errmsg = 6;
                    _hasSession = true;
                    RRPandora.PandoraClient._authenticationToken = musicBox.User.AuthorizationToken;
                    errmsg = 7;
                    RRPandora.PandoraClient._lid = musicBox.User.ListenerId;
                    errmsg = 8;
                    pclient = new RRPandora.PandoraClient();
                    errmsg = 9;
                    pclient.SearchComplete += new EventHandler<RRPandora.EventArgs<List<RRPandora.SearchResult>>>(pclient_SearchComplete);

                    RefreshStations();
                    _playHandle.Set();
                    errmsg = 10;


                    if (IsActive || IsResumingActive)
                    {
                        ToLog("Resuming audio stream");
                        PlayInWinamp(musicBox.GetNextSong(false).AudioURL, true);
                        //set is resuming active false to reset it
                        IsResumingActive = false;
                    }
                    else
                    {
                        ToLog("Resume initializations was interrupted due to RR having an active source not matching RRPandora");
                    }

                    if (SDK.GetInfo("RRSCREEN").ToLower().Contains("rrpandora_list"))
                    {
                        System.Threading.Thread.Sleep(500);
                        SDK.Execute("CLCLEAR;ALL");
                        SDK.Execute("CLLOAD;" + DPath + "Support_files\\station_list.txt");
                        SDK.Execute("CLFIND;" + _currentStationId);
                        StatusTimer.Enabled = true;
                        SongProgressTimer.Enabled = true;
                        
                    }
                    StatusTimer.Enabled = true;
                    SongProgressTimer.Enabled = true;
                    
                }
                else
                {
                    SDK.ErrScrn("RRPandora", "Error During Login", "An error occured during login.  Please check your credentials  ");
                }
            }
            catch (Exception ex)
            {
                SDK.ErrScrn("RRPandora", "Error During Authentication", "An error occured authentication:  " + errmsg.ToString() + " - " + ex.Message);
            }
        }

        

       // void player_PlaybackEvent(EventCode eventCode)
       // {
           // try
           // {
             //   if (eventCode == EventCode.Complete)
               // {
                    //PlayNext(false);
                //    PlayInWinamp(musicBox.GetNextSong(false).AudioURL, true);
                //    player.Position = 0;
                //}
                //if ((eventCode != EventCode.Paused) && (eventCode != EventCode.ClockChanged) && (eventCode != EventCode.Complete))
                    
                        //ToLog(eventCode.ToString() + " - " + DateTime.Now.ToLongTimeString());
            //}
           // catch (Exception err)
            //{
               
              //      ToLog("error with play handler: " + err.Message);
            //}
       // }



        void ConnectionWorker_DoWork(object sender, DoWorkEventArgs e)
        {
            _waitHandle.WaitOne();
        }

        void ConnectionWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            try
            {
                _isConnected = true;
                if (!AuthWorker.IsBusy)
                    AuthWorker.RunWorkerAsync();
                
                    ToLog("Authorization worker started");
            }
            catch (Exception err)
            {
                
                    ToLog(err.Message);
            }
        }

        #endregion
    }
	
	#region RR SDK

	[ComVisible(false)]
	static public class SDK
	{
		static bool _Created;
		static object RRSDK;
		static Type objAddType;
		static bool _Enabled = true;

		static public void SetSDK()
		{
			try
			{
				objAddType = Type.GetTypeFromProgID("RideRunner.SDK");
				RRSDK = Activator.CreateInstance(objAddType);
				if (RRSDK != null)
				{
					_Created = true;

					_Enabled = true;
				}
			}
			catch 
			{
				// "Failed to create RideRunner SDK Com Interface"
			}
		}

		static public bool Created
		{
			get { return _Created; }
		}

		static public bool Enabled
		{
			 set { _Enabled = value; }
		}

		static public void DoLog(string message)
		{
			if (RRSDK == null)
				return;

			if (_Enabled == false)
				return;

			objAddType.InvokeMember("RRLog", BindingFlags.InvokeMethod, null, RRSDK, new object[] { message });
		}

		static public void Execute(string CMD)
		{
			if (RRSDK == null)
				return;

			if (_Enabled == false)
				return;

			objAddType.InvokeMember("Execute", BindingFlags.InvokeMethod, null, RRSDK, new object[] { CMD, false });
		}

		static public void Execute(string CMD, bool Wait)
		{
			if (RRSDK == null)
				return;

			if (_Enabled == false)
				return;

			objAddType.InvokeMember("Execute", BindingFlags.InvokeMethod, null, RRSDK, new object[] { CMD, Wait });
		}

		static public string GetInfo(string inf)
		{
			if (RRSDK == null)
				return null;

			return (string)objAddType.InvokeMember("GetInfo", BindingFlags.InvokeMethod, null, RRSDK, new object[] { inf, "" });
		}

		static public string GetInfo(string inf, string FMT)
		{
			if (RRSDK == null)
				return null;

			if (_Enabled == false)
				return null;

			return (string)objAddType.InvokeMember("GetInfo", BindingFlags.InvokeMethod, null, RRSDK, new object[] { inf, FMT });
		}

		static public string GetInd(string ind)
		{
			if (RRSDK == null)
				return null;

			if (_Enabled == false)
				return null;

			return (string)objAddType.InvokeMember("GetInd", BindingFlags.InvokeMethod, null, RRSDK, new object[] { ind, "" });
		}

		static public string GetInd(string ind, string SCR)
		{
			if (RRSDK == null)
				return null;

			if (_Enabled == false)
				return null;

			return (string)objAddType.InvokeMember("GetInd", BindingFlags.InvokeMethod, null, RRSDK, new object[] { ind, SCR });
		}

		static public void ErrScrn(string Title, string Subject, string Message, int Timeout)
		{
			if (RRSDK == null)
				return;

			if (_Enabled == false)
				return;

			objAddType.InvokeMember("ErrScrn", BindingFlags.InvokeMethod, null, RRSDK, new object[] { Title, Subject, Message, Timeout });
		}

		static public void ErrScrn(string Title, string Subject, string Message)
		{
			SDK.ErrScrn(Title, Subject, Message, (int)-1);
		}

		static public void SetUserVar(string userVariable, string value)
		{
			if (RRSDK == null)
				return;

			if (_Enabled == false)
				return;

			objAddType.InvokeMember("SetUserVar", BindingFlags.InvokeMethod, null, RRSDK, new object[] { userVariable, value });
		}

		static public string GetUserVar(string userVariable)
		{
			if (RRSDK == null)
				return null;

			if (_Enabled == false)
				return null;

			return (string)objAddType.InvokeMember("GetUserVar", BindingFlags.InvokeMethod, null, RRSDK, new object[] { userVariable });
		}

		static public void AddRepeatCMD(string command)
		{
			if (RRSDK == null)
				return;

			if (_Enabled == false)
				return;

			objAddType.InvokeMember("AddRepeatCMD", BindingFlags.InvokeMethod, null, RRSDK, new object[] { command });
		}
	}
	#endregion


}